package common

import (
	"github.com/dgrijalva/jwt-go"
	"jiaqin/model"
	"time"
)

var jwtkey = []byte("a_secret_cret") //定义一个加密用的签名密钥
// []byte(string)，将string转为[]byte
//string就是一系列字节，而[]byte也可以表达一系列字节，那么实际运用中应当如何取舍？
//string可以直接比较，而[]byte不可以，所以[]byte不可以当map的key值。
//因为无法修改string中的某个字符，需要粒度小到操作一个字符时，用[]byte。
//string值不可为nil，所以如果你想要通过返回nil表达额外的含义，就用[]byte。
//[]byte切片这么灵活，想要用切片的特性就用[]byte。
//需要大量字符串处理的时候用[]byte，性能好很多。

type Claims struct { //定义token的claims
	UserID uint
	jwt.StandardClaims
}

func ReleaseToken(user model.User)(string,error)  { //在登陆成功后，调用该方法发放token
	expirationTime:=time.Now().Add(7*24*time.Hour) //token过期时间：7天

	claims:=&Claims{  //定义一个token
		UserID: user.ID,
		StandardClaims:jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(), //token什么时候过期
			IssuedAt: time.Now().Unix(), //什么时候发放的
			Issuer: "Bisnow-Bao", //是发放的token
			Subject: "user token", //主题
		},
	}
	token:=jwt.NewWithClaims(jwt.SigningMethodHS256,claims)
	tokenString,err:=token.SignedString(jwtkey) //使用密钥生成给客户端的token（token加密）

	if err!=nil{
		return " ",err
	}
	return tokenString,nil
}
// token由三部分组成：第一部分是header：储存token使用的加密协议，第二部分是payload，储存claims中储存的信息，
// 通过 base64来解密可得第一部分 {"alg":"HS256","typ":"JWT"}
// 第二部分{"UserID":6,"exp":1633321667,"iat":1632716867,"iss":"Bisnow-Bao","sub":"user token"}
// 第三部分是前两部分再加上jwtkey来hash生成的值，

//"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjYsImV4cCI6MTYzMzMyMTY2NywiaWF0IjoxNjMyNzE2ODY3LCJpc3MiOiJCaXNub3ctQmFvIiwic3ViIjoidXNlciB0b2tlbiJ9.luL91k0Hmlc9APMgEG8TFA-hwPm48NeRhCvnzj3Hoo4"


func ParseToken(tokenString string) (*jwt.Token,*Claims,error) {
	Claims:=&Claims{}
	token,err:= jwt.ParseWithClaims(tokenString,Claims, func(token *jwt.Token) (interface{}, error) {
		return jwtkey,nil
	}) //从tokenString里解析出claims然后返回
	return token,Claims,err
}